#include <iostream>
#include "LogicServerLogin.h"
#include "LogicUserBase.h"
#include <stdexcept>

using namespace std;

LogicLoginManager * LogicLoginManager::plogin = NULL;
const int LogicLoginManager::score_gate[max_gate_id] = {1, 2, 3, 5, 8, 12, 17, 23, 30, 38};
const int LogicLoginManager::level_score[max_level] = {30,80,110,190,300,490,790,1280,2070,3350,5420,8770,14190,22960,37150,60110,97260,157370,254630,412000,	666630,1078630,1745260,2823890,4569150,7393040,11962190,19355230,31317420,50672650};

LogicLoginManager * LogicLoginManager::GetInstance()
{
	if (NULL == plogin)
	{
		plogin = new LogicLoginManager;
	}

	//连接数据库
	LogicUserBase::GetInstance();

	return plogin;
}

int LogicLoginManager::Process(Base::LoginReq * req, Base::LoginResp * resp)
{
	LogicUserBase * logicbase = LogicUserBase::GetInstance();

	const string & openid = req->openid();

	DataBase database;

	int ret = logicbase->GetBase(openid.c_str(), database);

	if (ret)
	{
		throw runtime_error("wrong openid");
	}

    //设置响应的消息内容
	database.SetMessage(resp->mutable_base());
	database.SetMessage(resp->mutable_flex());

	return 0;
}

int LogicLoginManager::Process(Base::HitBrickReq * req, Base::HitBrickResp * resp)
{
	unsigned uid = req->uid();
	unsigned gateid = req->gateid();

	if (gateid > max_gate_id)
	{
		throw runtime_error("gateid_param_error");
	}

	//参数验证
	LogicUserBase * logicbase = LogicUserBase::GetInstance();
	DataBase database;

	//只需获取部分用户数据
	int ret = logicbase->GetBaseLimit(uid, database);

	if (ret)
	{
		throw runtime_error("wrong uid");
	}

	//更新用户数据分数
	//暂时直接写死，本来应该写在配置文件中
	database.hit += 1;
	AddScore(database, score_gate[gateid - 1]);

	//更新玩家数据
	logicbase->UpdateBaseLimit(database);

	//返还前端
	database.SetMessage(resp->mutable_flex());

	return 0;
}

int LogicLoginManager::Process(Base::BallDeadReq * req, Base::BallDeadResp * resp)
{
	bool issuccess = req->issuccess();
	unsigned gateid = req->gateid();

    //设置响应的消息内容
	if (!issuccess)
	{
		//如果失败，设置失败的消息
		resp->set_rettype(Base::End);
		resp->set_nextgateid(gateid);
		resp->set_msg("很抱歉，您阵亡了!!!!!");
	}
	else if (gateid < max_gate_id)
	{
		//通过下一关
		resp->set_rettype(Base::Next);

		gateid += 1;
		resp->set_nextgateid(gateid);

		char msg[100] = {0};
		sprintf(msg, "恭喜您通过本关，即将进入第%u关!", gateid);

		resp->set_msg(msg);
	}
	else
	{
		//结束，通关
		resp->set_rettype(Base::End);
		resp->set_nextgateid(gateid);
		resp->set_msg("恭喜您成功通关游戏!");
	}

	return 0;
}

int LogicLoginManager::AddScore(DataBase & base, unsigned score)
{
	int oldlevel = GetLevel(base.score);

	base.score += score;
	unsigned max_score = level_score[max_level - 1];

	if (base.score > max_score)
	{
		//经验达到最大
		base.score = max_score;
		base.level = max_level;

		return 0;
	}

	base.level = GetLevel(base.score);

	return 0;
}

int LogicLoginManager::GetLevel(unsigned score)
{
	int level = 0;

	if (score >= level_score[max_level - 1])
	{
		return max_level;
	}

	//数组中每个下标对应的值是结束值
	//所以，找出第一个分数大于下标的值即可
	for(int i = 0; i < max_level; ++i)
	{
		if (level_score[i] > score)
		{
			level = i + 1;
			break;
		}
	}

	return level;
}

